from os import truncate
from django import db
from django.contrib import auth
from django.shortcuts import render, redirect
from django.urls.base import reverse  # 反向解析url
from django.http import JsonResponse, HttpResponse
from itsdangerous import TimedJSONWebSignatureSerializer as Serialize  # 制造token
from itsdangerous import SignatureExpired  # 获取token的异常
from django.core.mail import send_mail
from django.conf import settings
from user.models import User, Address
from goods.models import GoodsSKU
from order.models import OrderInfo,OrderGoods
from celery_tasks.tasks import send_register_active_email  # 注册发生邮件celery
from django.views.generic import View  # post，get请求分别接受
from django.contrib.auth import authenticate, login, logout  # 验证用户,记住用户状态,退出登录
from django.contrib.auth.decorators import login_required  # 检查登录状态 没有登录那么跳转到登录页面
# 目前的了解就是按照setting里面的配置更简单的创建redis实例
from django_redis import get_redis_connection
from django.core.paginator import Paginator

# Create your views here.


def register(request):
    return render(request, 'user/register.html')


def register_handle(request):
    username = request.POST.get('username')
    password = request.POST.get('password')
    email = request.POST.get('email')

    user = User.objects.create_user(username, email, password)
    user.is_active = 0
    user.save()

    # 给用户邮箱发送信息，让他激活  这个为了不要在url后面暴露用户信息 所以借助加密函数加密
    # 加密秘钥位settings里面的秘钥 过期时间为一个小时
    serialize = Serialize(settings.SECRET_KEY, 3600)
    token = serialize.dumps({'confirm': user.id})
    token = token.decode()  # 默认为bytes类型 把他转换为utf8的字符串

    # 发邮件的事情交给celery
    send_register_active_email.delay(email, username, token)

    return redirect(reverse('user:login'))


def ajax_experience_username(request):
    username = request.POST.get('username')
    user = User.objects.filter(username=username)
    exsists = 0
    if len(user) == 0:
        exsists = 0
    else:
        exsists = 1

    return JsonResponse({'exsists': exsists})


def active(request, token):
    serialize = Serialize(settings.SECRET_KEY, 3600)
    try:
        info = serialize.loads(token)
        info = info['confirm']
        user = User.objects.get(id=info)
        user.is_active = 1
        user.save()
        return redirect(reverse('user:login'))
    except SignatureExpired as e:
        return HttpResponse('激活链接已过期')


class Login(View):
    def get(self, request):
        # 如果有记住用户名就给他拿出来
        if 'username' in request.COOKIES:
            username = request.COOKIES.get('username')
            check = 'checked'
        else:
            username = ''
            check = ''
        return render(request, 'user/login.html', {'username': username, 'check': check})

    def post(self, request):
        # 接受数据
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 校验数据
        user = authenticate(request, username=username, password=password)
        if user is not None:
            # 用户名正确
            if user.is_active:
                # 用户已激活
                login(request, user)  # 记住用户登录状态
                # 检查用户是从那个页面跳转过来的
                # 默认是首页
                next_url = request.GET.get('next', reverse('goods:index'))
                response = redirect(next_url)
                # 检查是否要记住用户名
                check = request.POST.get('check')
                if check:
                    response.set_cookie(
                        'username', username, max_age=3600*24*7)
                else:
                    response.delete_cookie('username')
                return response
            else:
                # 未激活
                return render(request, 'user/login.html', {'errmsg': '账户未激活'})
        else:
            # 用户名错误
            return render(request, 'user/login.html', {'errmsg': '用户名或密码错误'})


def logout_btn(request):
    # 退出登录，删除session
    logout(request)

    return redirect(reverse('goods:index'))


@login_required
def user(request):
    # django会给每个request对象添加user属性，is_authenticated属性如果为真证明用户登录过了，为false说明用户没有登录。false的时候他是anonymousUser的实例对象
    # 这个user对象可以在模板上直接使用，就叫user

    # 显示用户基本信息
    user_default = Address.objects.get_default_address(request.user)
    # 显示用户最近浏览
    # 原来的创建redis对象方法
    # from redis import StrictRedis
    # sr = StrictRedis(host='127.0.0.1',port='6379',db='10')
    # django提供的链接方法 ，配置在settings里面
    con = get_redis_connection('history')
    history_key = 'history_%d' % request.user.id
    # 获取商品id
    sku_id = con.lrange(history_key, 0, 4)
    # 从mysql获取对应的商品
    # goods_li  = GoodsSKU.objects.filter(id__in=sku_id)
    # 从mysql获取的数据循序编乱了，需要遍历重新排队
    # 也可以通过两层循环改正过来,下面直接一个一个来查
    goods_li = []
    for id in sku_id:
        good = GoodsSKU.objects.get(id=id)
        goods_li.append(good)

    context = {'page_name': 'center',
               'user_default': user_default,
               'goods':goods_li,
               }
    return render(request, 'user/user.html', context=context)


@login_required
def user_order(request,page):

    user = request.user

    # 获取订单信息
    orders = OrderInfo.objects.filter(user=user).order_by('-create_time')

    # 遍历订单头
    for order in orders:
        order_goods_list = OrderGoods.objects.filter(order=order)
        # 动态添加属性
        order.order_goods_list = order_goods_list
        order.status_name = OrderInfo.ORDER_STATUS[order.order_status]
        order.methos_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method]

        # 计算总计
        total_price = 0

        # 遍历订单行
        for order_goods in order_goods_list:
            # 在订单商品模型类中记录了count的
            order_goods.amount = order_goods.price * order_goods.count
            # 计算总价
            total_price += order_goods.amount
        
        order.total_price = total_price

        # 分页
        paginator = Paginator(orders,2)

        # 校验页码
        try:
            page = int(page)
        except:
            page = 1

        if page > paginator.num_pages:
            page = 1
        
        # 控制页面上显示的页码 最多显示5个
        # 如果页码不够5那么显示的就是12345
        # 如果当前页码是前三页显示的也是12345
        # 如果当前页是最后3页 显示最后5页
        # 其他情况当前页，前两页，后两页
        num_pages = paginator.num_pages
        if num_pages<5:
            pages = range(1,num_pages+1)
        elif page <=3:
            pages = range(1,6)
        elif num_pages - page <= 2:
            pages = range(num_pages-4, num_pages+1)
        else:
            pages = range(page-2,page+3)

        goods_page = paginator.page(page)

        context={"pages":pages, "goods_page":goods_page,'page_name': 'order'}

    return render(request, 'user/user_order.html',context)


class User_site(View):
    def get(self, request):
        # 先验证用户有没有默认的收货地址
        # try:
        #     user_default = Address.objects.get(user = request.user,is_default=True)
        # except Exception as e:
        #     user_default = None
        # 使用自定义的模型类管理器的方法
        user_default = Address.objects.get_default_address(request.user)
        return render(request, 'user/user_site.html', {'page_name': 'site', 'add_user': user_default})

    def post(self, request):
        name = request.POST.get('name')
        addr = request.POST.get('addr')
        zip_code = request.POST.get('zip_code')
        phone = request.POST.get('phone')
        # request会携带者登陆者的信息
        user = request.user
        # try:
        #     user_default = Address.objects.get(user = user ,is_default=True)
        # except Exception as e:
        #     user_default = None

        # 使用自定义的模型类管理器的方法
        user_default = Address.objects.get_default_address(user)

        if user_default:
            is_default = False
        else:
            is_default = True

        Address.objects.create(user=user, receiver=name, addr=addr,
                               zip_code=zip_code, phone=phone, is_default=is_default)
        return redirect(reverse('user:user_site'))
